<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/8/14
 * Time: 11:48
 */
namespace App\Services\Xinyan;

use App\Repositories\RepaymentBillRepository;
use App\Repositories\UserBankCardRepository;
use App\Repositories\UserCreditCardRepository;
use App\Repositories\UserIdentityCheckRepository;
use App\Repositories\UserRepository;
use App\Services\AlipayValidateCardInfo\BankCardInfoService;
use App\Services\CommonService;
use App\Services\MessageService;
use App\Services\UploadOSSorStorage;
use App\Services\UserLevelRelationsService;
use App\Services\UserPassageService;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class IdentityCardService extends CommonService
{
    protected $userRepository;
    protected $userIdentityCheckRepository;
    protected $userBankCardRepository;
    protected $userCreditCardRepository;
    protected $repaymentBillRepository;
    protected $messageService;
    protected $userPassageService;
    protected $userLevelRelationsService;

    public function __construct(UserRepository $userRepository, UserIdentityCheckRepository $userIdentityCheckRepository,
                                UserBankCardRepository $userBankCardRepository, UserCreditCardRepository $userCreditCardRepository,
                                RepaymentBillRepository $repaymentBillRepository, MessageService $messageService,
                                UserPassageService $userPassageService, UserLevelRelationsService $userLevelRelationsService)
    {
        $this->userRepository = $userRepository;
        $this->userIdentityCheckRepository = $userIdentityCheckRepository;
        $this->userBankCardRepository = $userBankCardRepository;
        $this->userCreditCardRepository = $userCreditCardRepository;
        $this->repaymentBillRepository = $repaymentBillRepository;
        $this->messageService = $messageService;
        $this->userPassageService = $userPassageService;
        $this->userLevelRelationsService = $userLevelRelationsService;
    }

    /**
     * 身份证认证
     * @param $idCard
     * @param $idHolder
     * @param $isPhoto
     * @param $industryType
     * @return mixed
     */
    public function identityIdCard($idCard, $idHolder, $isPhoto, $industryType)
    {
        $certificationBankCardMsgAuth = new CertificationBankCardMsgAuth();
        $result = $certificationBankCardMsgAuth->identityIdCard($idCard, $idHolder, $isPhoto, $industryType);
        return $result;
    }

    /**
     * 银行三四要素验证
     * @param $accNo
     * @param $mobile
     * @param $cardType
     * @param $validDateYear
     * @param $validDateMonth
     * @param $validNo
     * @param $verifyElement
     * @param $idCard
     * @param $idHolder
     * @param $industryType
     * @param $productType
     * @return mixed
     */
    public function identityBankCardThreeFourPoint($accNo, $mobile, $verifyElement, $idCard, $idHolder, $industryType, $productType)
    {
        $certificationBankCardMsgAuth = new CertificationBankCardMsgAuth();
        $result = $certificationBankCardMsgAuth->identityBankCardThreeFourPoint($accNo, $mobile, $verifyElement, $idCard,
            $idHolder, $industryType, $productType);
        return $result;
    }

    /**
     * 身份认证和银行卡三四要素接口
     * @param $idCard
     * @param $isPhoto
     * @param $accNo
     * @param $mobile
     * @param $cardType
     * @param $validDateYear
     * @param $validDateMonth
     * @param $validNo
     * @param $verifyElement
     * @param $idHolder
     * @param $industryType
     * @param $productType
     */
    public function identityAuth($userId, $code, $idCard, $isPhoto, $accNo, $mobile, $verifyElement, $idHolder, $industryType, $productType)
    {
        //先检验图片是否上传
        $userIdentityCheckRepository = $this->userIdentityCheckRepository->byUserId($userId);
        if (empty($userIdentityCheckRepository)) return $this->responseJson(10303);//请先上传身份照
        //验证身份证号码是否正确
        if (!validation_filter_id_card($idCard)) {
            return $this->responseJson(422, [], false, '身份证号码格式不正确', '身份证号码格式不正确');
        }
        //验证银行卡号是否正确
        if (!check_bankCard($accNo)) {
            return $this->responseJson(422, [], false, '银行卡号不正确', '银行卡号不正确');
        }
        //验证码是否正确
        $isCheck = $this->checkCode($mobile, $code, 'truename_auth');
        if (!$isCheck) {
            return $this->responseJson(10110);//短信验证码不正确
        }
        $certificationBankCardMsgAuth = new CertificationBankCardMsgAuth();
        $idcardResult = $certificationBankCardMsgAuth->identityIdCard($idCard, $idHolder, $isPhoto, $industryType);
        if ($idcardResult['success'] && 0 == $idcardResult['data']['code']) {
            //获取银行卡信息
            $bankCardInfoService = new BankCardInfoService();
            $cardInfo = $bankCardInfoService->getBankInfo($accNo);
            if (empty($cardInfo) || !isset($cardInfo['card_bin'])) {
                return $this->responseJson(10309);//该卡片信息暂无接入
            }
            if ('DC' != $cardInfo['card_type']) {
                return $this->responseJson(422, [], false, '非储蓄卡', '非储蓄卡');
            }
            $bankCardResult = $certificationBankCardMsgAuth->identityBankCardThreeFourPoint($accNo, $mobile, $verifyElement, $idCard,
                $idHolder, $industryType, $productType);
            if ($bankCardResult['success'] && 0 == $bankCardResult['data']['code']) {
                //开启事务
                DB::beginTransaction();
                try {
                    //更新用户身份信息与通过实名认证的状态
                    $user = $this->userRepository->byId($userId);
                    $userInfo = [
                        'realname' => $idHolder,
                        'idcard_number' => $idCard,
                        'is_truename_auth' => 1,
                    ];
                    $invitedCode = $user->invited_code;
                    $user->update($userInfo);
                    //身份认证与银行卡都完成，创建数据
                    $data = [
                        'user_id' => $userId,
                        'bank_no' => $accNo,
                        'bank_code' => $cardInfo['bank_code'],
                        'bank_description' => $cardInfo['bank_name'],
                        'bank_mobile' => $mobile,
                        'card_description' => $cardInfo['card_description'],
                        'card_bin' => $cardInfo['card_bin'],
                    ];
                    $userIdentityCheckRepository->update(array_merge($data, ['update_time' => time()]));
                    $this->userBankCardRepository->create(array_merge($data, ['is_default' => 1, 'create_time' => time()]));
                    //邀请人是否需要升级高级会员
                    $this->userLevelRelationsService->invitedAuthToLevel3($userId);
                    DB::commit();
                    //发送实名成功消息提醒
                    $this->messageService->messageTemplate(5, $invitedCode, '', '',
                        0, '', '', 0, '', '');
                    return $this->responseJson(0);
                } catch (\Exception $e) {
                    DB::rollBack();
                    return $this->responseJson(400, [], false, $e->getMessage(), '');
                }
            } else {
                if ($bankCardResult['success']) {
                    return $this->responseJson(422, [], false, $bankCardResult['data']['org_desc'], $bankCardResult['data']['org_desc']);
                } else {
                    return $this->responseJson(422, [], false, $bankCardResult['errorMsg'], $bankCardResult['errorMsg']);
                }
            }
        } else {
            if ($idcardResult['success']) {
                return $this->responseJson(422, [], false, $idcardResult['data']['desc'], $idcardResult['data']['desc']);
            } else {
                return $this->responseJson(422, [], false, $idcardResult['errorMsg'], $idcardResult['errorMsg']);
            }
        }
    }


    /**
     * 身份认证上传图片
     * @param $request
     * @param $id
     * @return bool|\Illuminate\Http\JsonResponse|string
     */
    public function identityUpload($request, $id)
    {
        //上传新图片
        $idcardPicFrontUploadFilePath = $this->upload('alioss', 'identity', $request->idcard_pic_front);
        if (is_object($idcardPicFrontUploadFilePath)) return $idcardPicFrontUploadFilePath;
        $idcardPicBackUploadFilePath = $this->upload( 'alioss', 'identity', $request->idcard_pic_back);
        if (is_object($idcardPicBackUploadFilePath)) return $idcardPicBackUploadFilePath;
        $bankcardPicFrontUploadFilePath = $this->upload( 'alioss', 'identity', $request->bankcard_pic_front);
        if (is_object($bankcardPicFrontUploadFilePath)) return $bankcardPicFrontUploadFilePath;
        $idcardPicMiddleUploadFilePath = $this->upload( 'alioss', 'identity', $request->idcard_pic_middle);
        if (is_object($idcardPicMiddleUploadFilePath)) return $idcardPicMiddleUploadFilePath;
        $data = [
            'idcard_pic_front' => $idcardPicFrontUploadFilePath,
            'idcard_pic_back' => $idcardPicBackUploadFilePath,
            'bankcard_pic_front' => $bankcardPicFrontUploadFilePath,
            'idcard_pic_middle' => $idcardPicMiddleUploadFilePath
        ];
        $user = $this->userIdentityCheckRepository->byUserId($id);
        if (empty($user)) {
            $data['user_id'] = $id;
            $data['create_time'] = time();
            $this->userIdentityCheckRepository->create($data);
        } else {
            //删除旧图片
            if (!empty($user->idcard_pic_front)) {
                $uploadOSSorStorage = new UploadOSSorStorage();
                $uploadOSSorStorage->deleteOSSorStorageLocal($user->idcard_pic_front, "alioss");
            }
            if (!empty($user->idcard_pic_back)) {
                $uploadOSSorStorage = new UploadOSSorStorage();
                $uploadOSSorStorage->deleteOSSorStorageLocal($user->idcard_pic_back, "alioss");
            }
            if (!empty($user->bankcard_pic_front)) {
                $uploadOSSorStorage = new UploadOSSorStorage();
                $uploadOSSorStorage->deleteOSSorStorageLocal($user->bankcard_pic_front, "alioss");
            }
            if (!empty($user->idcard_pic_middle)) {
                $uploadOSSorStorage = new UploadOSSorStorage();
                $uploadOSSorStorage->deleteOSSorStorageLocal($user->idcard_pic_middle, "alioss");
            }
            //更新几张图片
            $data['user_id'] = $id;
            $data['update_time'] = time();
            $user->update($data);
        }
        $fileUpload = [
            'idcard_pic_front' => getOssImageUrl($idcardPicFrontUploadFilePath),
            'idcard_pic_back' => getOssImageUrl($idcardPicBackUploadFilePath),
            'bankcard_pic_front' => getOssImageUrl($bankcardPicFrontUploadFilePath),
            'idcard_pic_middle' => getOssImageUrl($idcardPicMiddleUploadFilePath)
        ];
        return $this->responseJson(0, $fileUpload);
    }

    /**
     * 添加绑定借记卡
     * @param $userId
     * @param $code
     * @param $accNo
     * @param $mobile
     * @param $validDateYear
     * @param $validDateMonth
     * @param $validNo
     * @param $verifyElement
     * @param $industryType
     * @param $productType
     * @return \Illuminate\Http\JsonResponse
     */
    public function bindBankCard($user, $code, $accNo, $mobile, $verifyElement, $industryType, $productType)
    {
        //验证银行卡号是否正确
        if (!check_bankCard($accNo)) {
            return $this->responseJson(422, [], false, '银行卡号不正确', '银行卡号不正确');
        }
        //验证码是否正确
        $isCheck = $this->checkCode($mobile, $code, 'bind_bank_card');
        if (!$isCheck) {
            return $this->responseJson(10110);//短信验证码不正确
        }
        $isExist = $this->userBankCardRepository->isExistBankNo($user['user_id'], $accNo);
        if (!empty($isExist)) {
            if (1 == $isExist->is_bind) {
                return $this->responseJson(10304);//储蓄卡不允许重复添加
            } else {
                $userBankCardRepository = $this->userBankCardRepository->byId($isExist->id);
                $userBankCardRepository->update([
                    'bank_mobile' => $mobile,
                    'is_bind' => 1,
                    'update_time' => time()
                ]);
                return $this->responseJson(0);
            }
        }
        //获取银行卡信息
        $bankCardInfoService = new BankCardInfoService();
        $cardInfo = $bankCardInfoService->getBankInfo($accNo);
        if (empty($cardInfo) || !isset($cardInfo['card_bin'])) {
            return $this->responseJson(10309);//该卡片信息暂无接入
        }
        if ('DC' != $cardInfo['card_type']) {
            return $this->responseJson(422, [], false, '非储蓄卡', '非储蓄卡');
        }
        $certificationBankCardMsgAuth = new CertificationBankCardMsgAuth();
        $bankCardResult = $certificationBankCardMsgAuth->identityBankCardThreeFourPoint($accNo, $mobile, $verifyElement,
            $user['idcard_number'], $user['realname'], $industryType, $productType);
        if ($bankCardResult['success'] && 0 == $bankCardResult['data']['code']) {
            $isFirstCard = $this->userBankCardRepository->byUserId($user['user_id']);
            if (empty($isFirstCard)) {
                $isDefault = 1;
            } else {
                $isDefault = 0;
            }
            //银行卡都完成，创建数据
            $data = [
                'user_id' => $user['user_id'],
                'bank_no' => $accNo,
                'bank_code' => $cardInfo['bank_code'],
                'bank_description' => $cardInfo['bank_name'],
                'bank_mobile' => $mobile,
                'card_description' => $cardInfo['card_description'],
                'card_bin' => $cardInfo['card_bin'],
                'is_default' => $isDefault,
                'create_time' => time(),
            ];
            $isExist = $this->userBankCardRepository->isExistBankNo($user['user_id'], $accNo);
            if (empty($isExist)) {
                $this->userBankCardRepository->create($data);//添加借记卡
            }
            return $this->responseJson(0);
        } else {
            if ($bankCardResult['success']) {
                return $this->responseJson(422, [], false, $bankCardResult['data']['org_desc'], $bankCardResult['data']['org_desc']);
            } else {
                return $this->responseJson(422, [], false, $bankCardResult['errorMsg'], $bankCardResult['errorMsg']);
            }
        }
        //使用卡宾验证卡片信息，卡种是否符合要求
//        $cardBinResult = $certificationBankCardMsgAuth->identityBankCardGuest($accNo, $industryType, $productType);
//        if ($cardBinResult['success'] && 0 == $cardBinResult['data']['code']) {
//            if ('1' != $cardBinResult['data']['card_type']) {
//                return $this->responseJson(422, [], false, '非借记卡', '非借记卡');
//            }
//        } else {
//            return $this->responseJson(422, [], false, '非借记卡', '非借记卡');
//        }
    }

    /**
     * 添加绑定信用卡
     * @param $userId
     * @param $code
     * @param $accNo
     * @param $mobile
     * @param $validDateYear
     * @param $validDateMonth
     * @param $validNo
     * @param $verifyElement
     * @param $industryType
     * @param $productType
     * @param $cvn2
     * @param $expireDate
     * @param $billDay
     * @param $repaymentDay
     * @param $repaymentMoney
     * @return \Illuminate\Http\JsonResponse
     */
    public function bindCreditCard($user, $code, $accNo, $mobile, $verifyElement, $industryType, $productType,
                                   $billDay, $repaymentDay, $creditLines, $repaymentMoney, $expireDate, $cvn2)
    {
        if ($billDay == $repaymentDay) {
            return $this->responseJson(422, [], false, '账单日与还款日相等', '账单日与还款日相等');
        }
        Log::info('添加信用卡卡号' . $accNo);
        //验证银行卡号是否正确
        if (!check_bankCard($accNo)) {
            return $this->responseJson(422, [], false, '银行卡号不正确', '银行卡号不正确');
        }
        //验证码是否正确
        $isCheck = $this->checkCode($mobile, $code, 'bind_credit_card');
        if (!$isCheck) {
            return $this->responseJson(10110);//短信验证码不正确
        }
        $repaymentMoneyAll = roundNo($repaymentMoney);//不四舍五入保留两位
        $isExist = $this->userCreditCardRepository->isExistUserBankNo($user['user_id'], $accNo);
        if (!empty($isExist)) {
            if (1 == $isExist->is_bind) {
                return $this->responseJson(10305);//信用卡不允许重复添加
            } else {
                $userBankCardRepository = $this->userCreditCardRepository->byId($isExist->id);
                $userBankCardRepository->update([
                    'bank_mobile' => $mobile,
                    'is_bind' => 1,
                    'bill_day' => $billDay,
                    'repayment_day' => $repaymentDay,
                    'credit_lines' => $creditLines,
                    'expire_date' => $expireDate,
                    'cvn2' => $cvn2,
                    'update_time' => time()
                ]);
                //一个月有上个和这个还款日，两个的处理
                $monthBillDate = getMonthBillDate($billDay, $repaymentDay);
                $bill = $this->repaymentBillRepository->getRepaymentBill($user['user_id'], $isExist->id, $monthBillDate);
                $billRepaymentDate = billRepaymentDate($billDay, $repaymentDay);
                if (date('Y-m') != $monthBillDate) {
                    $billRepaymentDate = [
                        'bill_last_date' => date('Ymd', strtotime("-1 months", strtotime($billRepaymentDate['bill_last_date']))),//上个月账单日
                        'repayment_last_date' => date('Ymd', strtotime("-1 months", strtotime($billRepaymentDate['repayment_last_date']))),//上个还款日
                        'bill_date' => $billRepaymentDate['bill_last_date'],//本月账单日
                        'repayment_date' => $billRepaymentDate['repayment_last_date'],//还款日
                        'diff_days' => diffDate($billRepaymentDate['bill_last_date'], $billRepaymentDate['repayment_last_date']),
                    ];
                }
                if (empty($bill)) {
                    $bill = [
                        'bill_sn' => makeOrderNo(),
                        'user_id' => $user['user_id'],
                        'credit_card_id' => $isExist->id,
                        'repayment_bill_money' => $repaymentMoneyAll,
                        'last_bill_date' => strtotime($billRepaymentDate['bill_last_date']) + 86400,
                        'bill_date' => strtotime($billRepaymentDate['bill_date']),
                        'repayment_date' => strtotime($billRepaymentDate['repayment_date']),
                        'lowest_repayment_money' => ceilDecimal($repaymentMoneyAll * 0.1, 2),//本期最低应还金额
                        'bill_status' => billStatus($billRepaymentDate['bill_date'], $billRepaymentDate['repayment_date'], $repaymentMoneyAll),
                        'month_bill_date' => $monthBillDate,
                        'create_time' => time(),
                    ];
                    $this->repaymentBillRepository->create($bill);
                } else {
                    $bill->update([
                        'repayment_bill_money' => $repaymentMoneyAll,
                        'last_bill_date' => strtotime($billRepaymentDate['bill_last_date']) + 86400,
                        'bill_date' => strtotime($billRepaymentDate['bill_date']),
                        'repayment_date' => strtotime($billRepaymentDate['repayment_date']),
                        'lowest_repayment_money' => ceilDecimal($repaymentMoneyAll * 0.1, 2),//本期最低应还金额
                        'bill_status' => billStatus($billRepaymentDate['bill_date'], $billRepaymentDate['repayment_date'], $repaymentMoneyAll),
                        'month_bill_date' => $monthBillDate,
                        'update_time' => time(),
                    ]);
                }
                return $this->responseJson(0, ['id' => $isExist->id]);
            }
        }
        //获取银行卡信息
        $bankCardInfoService = new BankCardInfoService();
        $cardInfo = $bankCardInfoService->getBankInfo($accNo);
        if (empty($cardInfo) || !isset($cardInfo['card_bin'])) {
            return $this->responseJson(10309);//该卡片信息暂无接入
        }
        if ('CC' != $cardInfo['card_type']) {
            return $this->responseJson(422, [], false, '非信用卡', '非信用卡');
        }
        $certificationBankCardMsgAuth = new CertificationBankCardMsgAuth();
        $bankCardResult = $certificationBankCardMsgAuth->identityBankCardThreeFourPoint($accNo, $mobile, $verifyElement,
            $user['idcard_number'], $user['realname'], $industryType, $productType);
        if ($bankCardResult['success'] && 0 == $bankCardResult['data']['code']) {
            //开启事务
            DB::beginTransaction();
            try {
                //身份认证与银行卡都完成，创建数据
                $data = [
                    'user_id' => $user['user_id'],
                    'bank_no' => $accNo,
                    'bank_code' => $cardInfo['bank_code'],
                    'bank_description' => $cardInfo['bank_name'],
                    'bank_mobile' => $mobile,
                    'card_description' => $cardInfo['card_description'],
                    'card_bin' => $cardInfo['card_bin'],
                    'is_bind' => 0,
                    'bill_day' => $billDay,
                    'repayment_day' => $repaymentDay,
                    'credit_lines' => $creditLines,
                    'expire_date' => $expireDate,
                    'cvn2' => $cvn2,
                    'create_time' => time(),
                ];
                $creditId = $this->userCreditCardRepository->insertGetId($data);//添加信用卡
                //一个月有上个和这个还款日，两个的处理
                $monthBillDate = getMonthBillDate($billDay, $repaymentDay);
                $billRepaymentDate = billRepaymentDate($billDay, $repaymentDay);
                if (date('Y-m') != $monthBillDate) {
                    $billRepaymentDate = [
                        'bill_last_date' => date('Ymd', strtotime("-1 months", strtotime($billRepaymentDate['bill_last_date']))),//上个月账单日
                        'repayment_last_date' => date('Ymd', strtotime("-1 months", strtotime($billRepaymentDate['repayment_last_date']))),//上个还款日
                        'bill_date' => $billRepaymentDate['bill_last_date'],//本月账单日
                        'repayment_date' => $billRepaymentDate['repayment_last_date'],//还款日
                        'diff_days' => diffDate($billRepaymentDate['bill_last_date'], $billRepaymentDate['repayment_last_date']),
                    ];
                }
                //添加本期账单
                $bill = [
                    'bill_sn' => makeOrderNo(),
                    'user_id' => $user['user_id'],
                    'credit_card_id' => $creditId,
                    'repayment_bill_money' => $repaymentMoneyAll,
                    'last_bill_date' => strtotime($billRepaymentDate['bill_last_date']) + 86400,
                    'bill_date' => strtotime($billRepaymentDate['bill_date']),
                    'repayment_date' => strtotime($billRepaymentDate['repayment_date']),
                    'lowest_repayment_money' => ceilDecimal($repaymentMoneyAll * 0.1, 2),//本期最低应还金额
                    'bill_status' => billStatus($billRepaymentDate['bill_date'], $billRepaymentDate['repayment_date'], $repaymentMoneyAll),
                    'month_bill_date' => $monthBillDate,
                    'create_time' => time(),
                ];
                $this->repaymentBillRepository->create($bill);
                DB::commit();
                return $this->responseJson(0, ['id' => $creditId]);
            } catch (\Exception $e) {
                DB::rollBack();
                return $this->responseJson(400, [], false, $e->getMessage(), '');
            }
        } else {
            if ($bankCardResult['success']) {
                return $this->responseJson(422, [], false, $bankCardResult['data']['org_desc'], $bankCardResult['data']['org_desc']);
            } else {
                return $this->responseJson(422, [], false, $bankCardResult['errorMsg'], $bankCardResult['errorMsg']);
            }
        }
        //使用卡宾验证卡片信息，卡种是否符合要求
//        $cardBinResult = $certificationBankCardMsgAuth->identityBankCardGuest($accNo, $industryType, $productType);
//        if ($cardBinResult['success'] && 0 == $cardBinResult['data']['code']) {
//            if ('2' != $cardBinResult['data']['card_type']) {
//                return $this->responseJson(422, [], false, '非信用卡', '非信用卡');
//            }
//        } else {
//            return $this->responseJson(422, [], false, '非信用卡', '非信用卡');
//        }
    }
}